package com.example.priorityobserver;

import java.util.Collections;
import java.util.List;

public class Observable<T> extends android.database.Observable<Observer<T>> {
	/**
	 * Adds an observer to the list. The observer cannot be null and it must not
	 * already be registered.
	 * 
	 * @param observer
	 *            the observer to register
	 * @throws IllegalArgumentException
	 *             the observer is null
	 * @throws IllegalStateException
	 *             the observer is already registered
	 */
	public void registerObserver(int index, Observer<T> observer) {
		if (observer == null) {
			throw new IllegalArgumentException("The observer is null.");
		}
		synchronized (mObservers) {
			if (mObservers.contains(observer)) {
				throw new IllegalStateException("Observer " + observer
						+ " is already registered.");
			}
			mObservers.add(index, observer);
		}
	}

	/**
	 * Adds an observer to the list. The observer cannot be null and it must not
	 * already be registered.
	 * 
	 * @param observer
	 *            the observer to register
	 * @throws IllegalArgumentException
	 *             the observer is null
	 * @throws IllegalStateException
	 *             the observer is already registered
	 */
	public void registerObserverEnd(Observer<T> observer) {
		if (observer == null) {
			throw new IllegalArgumentException("The observer is null.");
		}
		synchronized (mObservers) {
			if (mObservers.contains(observer)) {
				throw new IllegalStateException("Observer " + observer
						+ " is already registered.");
			}
			mObservers.add(mObservers.size(), observer);
		}
	}

	@Override
	public void registerObserver(Observer<T> observer) {
		registerObserverEnd(observer);
	}

	/**
	 * Adds an observer to the list. The observer cannot be null and it must not
	 * already be registered.
	 * 
	 * @param observer
	 *            the observer to register
	 * @throws IllegalArgumentException
	 *             the observer is null
	 * @throws IllegalStateException
	 *             the observer is already registered
	 */
	public void registerObserverFirst(Observer<T> observer) {
		if (observer == null) {
			throw new IllegalArgumentException("The observer is null.");
		}
		synchronized (mObservers) {
			if (mObservers.contains(observer)) {
				throw new IllegalStateException("Observer " + observer
						+ " is already registered.");
			}
			mObservers.add(0, observer);
		}
	}

	public void notifyObservers() {
		notifyObservers(null);
	}

	public void notifyObservers(T data) {
		for (Observer<T> i : mObservers)
			i.update(this, data);
	}

	public List<Observer<T>> getObservers() {
		return Collections.unmodifiableList(mObservers);
	}
}
